<?php

namespace App\Http\Controllers;

use App\Services\ArticleService;
use App\Services\CategoryService;
use App\Services\CommentService;
use App\Services\LinkService;
use App\Services\SettingService;
use App\Services\UserService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Str;
use Laravel\Lumen\Routing\Controller;

class HomeController extends Controller
{

    /**
     * @var ArticleService
     */
    private $articleService;

    /**
     * @var CategoryService
     */
    private $categoryService;

    /**
     * @var CommentService
     */
    private $commentService;

    public function __construct(ArticleService $articleService, CategoryService $categoryService, CommentService $commentService, SettingService $settingService)
    {
        $this->articleService = $articleService;
        $this->categoryService = $categoryService;
        $this->commentService = $commentService;

        $setting = $settingService->getSetting();
        view()->share('setting', $setting);

        $categories = $categoryService->getList('id, name, show_menu, alias', 1);
        view()->share('categories', $categories);
    }

    /**
     * 加载边栏数据
     */
    private function loadAside()
    {
        $newComments = $this->commentService->getNewList(10);
        view()->share('newComments', $newComments);

        $readArticles = $this->articleService->getReadRank(10);
        view()->share('readArticles', $readArticles);

        $archiveGroups = $this->articleService->getArchiveGroups();
        view()->share('archiveGroups', $archiveGroups);

        $linkService = new LinkService();
        $links = $linkService->getList();
        view()->share('links', $links);
    }

    /**
     * 加载文章列表数据
     */
    private function loadArticles(int $page, array $where)
    {
        $limit = 10;
        $columns = 'id, title, category_id, excerpt, published_at';

        $result = $this->articleService->getList($where, $limit, $columns);

        $pageHtml = pagination($result['total'], $page, $limit);

        view()->share('articles', $result['items']);
        view()->share('count', $result['total']);
        view()->share('pageHtml', $pageHtml);
    }

    /**
     * 首页
     */
    public function index(Request $request)
    {
        $this->validate($request, [
            'page' => 'bail|integer|min:1',
            's'    => 'bail|string|max:100',
        ]);

        $page = $request->input('page', 1);
        $search = $request->input('s', '');

        $data = [];
        $data['isHome'] = true;

        $where = [['status', 1]];

        if ($search) {
            $search = str_replace(['%', '_'], ['\%', '\_'], $search);
            $where[] = ['title', 'like', '%' . $search . '%'];
            $data['search'] = $search;
            $data['title'] = '搜索：' . $search;
        } else {
            $setting = view()->shared('setting');
            $data['title'] = $setting->home_title;
            $data['keywords'] = $setting->home_keywords;
            $data['description'] = $setting->home_description;
        }

        $this->loadArticles($page, $where);

        $this->loadAside();

        return view('home.list', $data);
    }

    /**
     * 分类
     */
    public function category(Request $request, string $alias)
    {
        $this->validate($request, [
            'page' => 'bail|integer|min:1',
        ]);

        $page = $request->input('page', 1);

        $category = $this->categoryService->getByAlias($alias);

        $where = [];
        $where[] = ['status', 1];
        $where[] = ['category_id', $category->id];

        $this->loadArticles($page, $where);

        $this->loadAside();

        $data = [];
        $data['title'] = $category->name;
        $data['keywords'] = $category->keywords;
        $data['description'] = $category->description;
        $data['categoryId'] = $category->id;

        return view('home.list', $data);
    }

    /**
     * 标签
     */
    public function tag(Request $request, string $tag)
    {
        $this->validate($request, [
            'page' => 'bail|integer|min:1',
        ]);

        $page = $request->input('page', 1);

        $tag = urldecode($tag);

        $where = [];
        $where[] = ['status', 1];
        $where[] = [function ($query) use ($tag) {
            $query->whereRaw('find_in_set(?, tags)', $tag);
        }];

        $this->loadArticles($page, $where);

        $this->loadAside();

        $data = [];
        $data['title'] = '标签：' . $tag;

        return view('home.list');
    }

    /**
     * 归档
     */
    public function archive(Request $request, string $year, string $month)
    {
        $this->validate($request, [
            'page' => 'bail|integer|min:1',
        ]);

        $page = $request->input('page', 1);

        $startTime = strtotime("$year-$month-01");
        $endTime = strtotime('last day of this month 23:59:59', $startTime);

        $where = [];
        $where[] = ['status', 1];
        $where[] = ['published_at', '>=', $startTime];
        $where[] = ['published_at', '<=', $endTime];

        $this->loadArticles($page, $where);

        $this->loadAside();

        $data = [];
        $data['title'] = '归档：' . date('Y年n月', $startTime);

        return view('home.list', $data);
    }

    /**
     * 查看文章
     */
    public function show(Request $request, string $year, string $month, int $id)
    {
        $data = [];

        $article = $this->articleService->show($id);

        if (date('Ym', $article->published_at) != $year . $month) {
            return redirect($article->url, 301);
        }

        if ($article->tags !== '') {
            $keywords = $article->tags . ',' . $article->category->name;
        } else {
            $keywords = $article->category->name;
        }

        $description = strip_tags($article->excerpt);
        $description = str_replace("\n", ' ', $description);
        $description = preg_replace('/\s{2,}/', ' ', $description);
        $description = Str::limit($description, 255);

        $data['title'] = $article->title;
        $data['keywords'] = $keywords;
        $data['description'] = $description;
        $data['article'] = $article;
        $data['categoryId'] = $article->category_id;
        $data['relatedArticles'] = $article->getRelatedArticles();

        //增加文章阅读量，同一个IP同一篇文章24小时只算1个阅读量
        $key = 'article_read_' . $id . '_' . $request->ip();
        if (!Cache::get($key)) {
            Cache::put($key, 1, 86400);
            $article->timestamps = false; //停用updated_at自动更新
            $article->increment('read_num');
        }

        return view('home.show', $data);
    }

    /**
     * 发表评论
     */
    public function comment(Request $request, UserService $userService)
    {
        $this->validate($request, [
            'article_id'      => 'bail|required|integer',
            'content'         => 'bail|required|string|min:5|max:500',
            'name'            => 'bail|required|string|max:20',
            'email'           => 'bail|required|string|max:50',
            'url'             => 'bail|url|max:50',
            'avatar'          => 'bail|required|integer|min:1|max:8',
            //'captcha_ticket'  => 'bail|required|string',
            //'captcha_randstr' => 'bail|required|string',
        ]);

        $data = $request->input();

        /*$userService->checkTencentCaptcha(
            $data['captcha_ticket'],
            $data['captcha_randstr'],
            $request->ip()
        );*/

        $this->commentService->add($data);

        return success();
    }

    /**
     * robots.txt
     */
    public function robots()
    {
        $content = "User-agent: *\n"
            . "Disallow: /admin/\n"
            . "Sitemap: " . config('app.url') . "/sitemap.xml\n";

        return response($content)->withHeaders(['Content-Type' => 'text/plain; charset=utf-8']);
    }

    /**
     * sitemap.xml
     */
    public function sitemap()
    {
        $articles = $this->articleService->getNewRank(10000);
        $lastTime = $articles[0]->updated_at;
        $lastmod = $lastTime->format('Y-m-d');
        $appUrl = config('app.url');

        $xml = "<url>"
            . "<loc>$appUrl/</loc>"
            . "<lastmod>$lastmod</lastmod>"
            . "<changefreq>weekly</changefreq>"
            . "<priority>0.8</priority>"
            . "</url>";

        foreach ($articles as $article) {
            $url = $appUrl . $article->url;
            $lastmod = $article->updated_at->format('Y-m-d');
            $xml .= "<url>"
                . "<loc>$url</loc>"
                . "<lastmod>$lastmod</lastmod>"
                . "<changefreq>monthly</changefreq>"
                . "<priority>0.8</priority>"
                . "</url>";
        }

        $xml = '<?xml version="1.0" encoding="utf-8"?>'
            . '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">'
            . $xml
            . '</urlset>';

        return response($xml)->withHeaders(['Content-type' => 'text/xml; charset=utf-8']);
    }

}
